﻿using System.Xml;
using System.Collections.Generic;
using SdmxMl.Common;
using SdmxMl.Helper;

namespace SdmxMl.Structure
{
    /// <summary>
    /// ContactType provides defines the contact information about a party. The id element is used to carry 
    /// user id information for the contact, whereas Name provides a human-readable name.
    /// </summary>
    public class ContactType
    {
        #region Properties

        public string Id { get; set; }
        public  MultiLang Name { get; set; }
        public MultiLang Department { get; set; }
        public MultiLang Role { get; set; }
        public ContactInfo ContactInfo { get; set; }
        
        /// <summary> Helper property to know if nothing filled</summary>
        public bool IsEmpty
        {
            get
            {
                return
                    Name.IsEmpty &&
                    Department.IsEmpty &&
                    Role.IsEmpty &&
                    string.IsNullOrEmpty(Id) &&
                    ContactInfo.MaxRows() == 0;
            }
        }
        #endregion

        #region Constructors

        private void Init()
        {
            Name = new MultiLang();
            Role = new MultiLang();
            Department = new MultiLang();
            Id = "";
            ContactInfo = new ContactInfo();
        }
        public ContactType()
        {
            Init();
        }

        public ContactType(XmlNode nodeArtefact, XmlNamespaceManager nsmgr, string tag)
        { 
            Init();
            XmlNode node = nodeArtefact.SelectSingleNode("./structure:" + tag, nsmgr);
            UpdateFromNode(node, nsmgr);
        }

        public void UpdateFromNode(XmlNode node, XmlNamespaceManager nsmgr)
        {
            if (node != null)
            {
                MultiLangNodeReader mr = new MultiLangNodeReader();
                mr.Read(Name, node, "Name", nsmgr, false);
                mr.Read(Department, node, "Department", nsmgr, false);
                mr.Read(Role, node, "Role", nsmgr, false);
                Id = Xmlhelper.GetNodeText(node, "./structure:id", nsmgr);

                ContactInfo = new ContactInfo(node, nsmgr);
            }
        }

        #endregion

        #region Clone

        public ContactType Clone()
        {
            ContactType c = new ContactType();
            c.Id = Id;
            c.Department = Department.Clone();
            c.ContactInfo = ContactInfo.Clone();
            c.Name = Name.Clone();
            c.Role = Role.Clone();

            return c;
        }
        #endregion

        #region XML serialize

        public void WriteXml(XmlTextWriter xw, string prefix, string tag)
        {
            if (!IsEmpty)
            {
                xw.WriteStartElement(prefix, tag, null);

                string nMprefix = SdmxNamespaceManager.SdmxTarget == SdmxVersion.SDMX_21 ?
                   "common" : prefix;
                Name.WriteXml(xw, nMprefix, "Name");
                Xmlhelper.WriteElementIfExist(xw, prefix, "id", Id);
                Department.WriteXml(xw, prefix, "Department");
                Role.WriteXml(xw, prefix, "Role");

                ContactInfo.WriteXml(xw, prefix, null);

                xw.WriteEndElement();
            }
        }

        #endregion

        #region String representation

        public override string ToString()
        {
            return Name.ToString();
        }
        #endregion

    }

    /// <summary>List of ContactsType</summary>
    public class ContactTypeList : List<ContactType>
    {
        #region XML Reader helper

        public void AddContactsFromNode(XmlNode nodeArtefact, XmlNamespaceManager nsmgr, string tag)
        {
            XmlNodeList nodeList = nodeArtefact.SelectNodes("./structure:" + tag, nsmgr);
            if (nodeList != null)
                foreach (XmlNode node in nodeList)
                {
                    ContactType ct = new ContactType();
                    ct.UpdateFromNode(node, nsmgr);
                    Add(ct);
                }
        }
        #endregion
    }
}
